#include <stdio.h>
#include <stdlib.h>
#include "mpi.h"

int main(int argc, char **argv)
{
    int size, wsize, rank, i, position;
    int arr1[15];
    char arr2[240];
    int failure = 0;
    MPI_Status status;
    
    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &wsize);

    if(wsize != 2)
    {
        fputs("Should be run with 2 processes\n", stderr);
        exit(1);
    }

    if(rank == 0)
    {
        /* fill arr1 with index values (+1) */
        for (i = 0; i < 15; i++)
            arr1[i] = i+1;

        /* print for proof */
        fputs("Should print 1-15\n", stdout);
        for (i = 0; i < 15; i++)
        {
            fprintf(stdout, "%d ", arr1[i]);
            if (arr1[i] != (i+1))
                failure = 1;
        }
        fputs("\n", stdout);

        /* test necessary pack size */
        MPI_Pack_size(15, MPI_INT, MPI_COMM_WORLD, &size);
        fprintf(stdout, "size = 60? %d\n", size);

        /* pack into byte array */
        position = 0;
        fputs("Packing data\n", stdout);
        MPI_Pack((void *)arr1, 15, MPI_INT, 
                (void *)arr2, 240, &position, MPI_COMM_WORLD);

        /* send packed data to process 1 */
        MPI_Send(arr2, 240, MPI_PACKED, 1, 9, MPI_COMM_WORLD);
    }
    
    /* zero out arr1 */
    for (i = 0; i < 15; i++)
        arr1[i] = 0;

    /* print for proof */
    fputs("Should print 15 zeroes\n", stdout);
    for (i = 0; i < 15; i++)
    {
        fprintf(stdout, "%d ", arr1[i]);
        if (arr1[i] != 0)
            failure = 1;
    }
    fputs("\n", stdout);

    if(rank == 1)
    {
        /* receive packed data from process 2 */
        MPI_Recv(&arr2, 240, MPI_PACKED, 0, 9, MPI_COMM_WORLD, &status);
        /* unpack values */
        position = 0;
        fputs("Unpacking data\n", stdout);
        MPI_Unpack((void *)arr2, 240, &position, 
                (void *)arr1, 15, MPI_INT, MPI_COMM_WORLD);

        /* print for proof */
        fputs("Should print 1-15\n", stdout);
        for (i = 0; i < 15; i++)
        {
            fprintf(stdout, "%d ", arr1[i]);
            if (arr1[i] != (i+1))
                failure = 1;
        }
        fputs("\n", stdout);
    }

    if (failure)
        fputs("FAILURE\n", stderr);
    else
        fputs("SUCCESS\n", stderr);

    MPI_Finalize();

    return(0);
}

